package org.twndmv.it;

import static org.junit.Assert.assertNotNull;

import java.util.Properties;

import javax.ejb.EJBAccessException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import junit.framework.Assert;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.twndmv.ejb.DmvTestUtilRemote;

public class DmvSecurityIT {
    
	private static Log log = LogFactory.getLog(DmvSecurityIT.class);
	private Context jndi;
	private static final String adminUser = System.getProperty("admin.user", "admin1");  
    private static final String raleighUser = System.getProperty("raleigh.user", "sysRaleigh");
    private static final String password = System.getProperty("password", "password");

   
    private static final String dmvTestUtilJNDI = System.getProperty("jndi.name.dmvTestUtil",
            "twnDmvEAR/twnDmvEJB/DmvTestUtilEJB!org.twndmv.ejb.DmvTestUtilRemote");
    
    private DmvTestUtilRemote dmvTestUtil;
    
    private Context runAs(String username, String password) throws NamingException {
        if (jndi!=null) {
                jndi.close();
        }
        Properties env = new Properties();
        if (username != null) {
            env.put(Context.SECURITY_PRINCIPAL, username);
            env.put(Context.SECURITY_CREDENTIALS, password);
        }
        log.debug(String.format("%s env=%s", username==null?"anonymous":username, env));
        System.out.println(String.format("%s env=%s", username==null?"anonymous":username, env));
        jndi=new InitialContext(env);
        return jndi;
    }
    
    @Before
	public void setUp() throws Exception {
		log.debug("===== TestDmvIT.init =====");

	        jndi = runAs(adminUser, password);
	        jndi.lookup("/"); //do a quick comms check of JNDI

	       
	        dmvTestUtil = (DmvTestUtilRemote)jndi.lookup(dmvTestUtilJNDI);
	        assertNotNull(dmvTestUtil);
	}
    
    /**
     * It is important to close the JNDI context in between tests
     */
    @After
    public void tearDown() throws NamingException {
        if (jndi != null) {
                jndi.close();
                jndi=null;
        }
    }
    
    @Test
    public void testSecurity() throws NamingException {
    	log.info("===== MayberryIT.testSecurity ======");
    	runAs(null, null);
    	//Try to reset DB as null user
    	try {
    		dmvTestUtil.resetAll();
    		Assert.fail("Failed to prevent reset DB");
    	} catch (EJBAccessException ejbae) {
    		assertNotNull(ejbae);
    	}
    	//Run as a user without admin role and see if they can resetDB.
    	runAs(raleighUser, password);
    	try {
    		dmvTestUtil.resetAll();
    		Assert.fail("Failed to prevent reset DB");
    	} catch (EJBAccessException ejbae) {
    		assertNotNull(ejbae);
    	}
    	//Run as admin user and see resetting work
    	runAs(adminUser, password);
    	try {
    		dmvTestUtil.resetAll();
    		assertNotNull(dmvTestUtil);
    	} catch (EJBAccessException ejbae) {
    		Assert.fail("Failed to allow admin reset DB");
    	}
	    
    }
    
}
